home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 3: Developer Tools / Linux Cubed Series 3 - Developer Tools.iso / devel / make / icmake-6.000 / icmake-6 / icmake / pp / lexer.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-03-01  |  5.9 KB  |  180 lines

  1. /*
  2. \funcref{lexer}{LEXER\_ lexer ()}
  3.     {}
  4.     {read token from the input}
  5.     {error(), directive(), getident()}
  6.     {}
  7.     {lexer.c}
  8.     {
  9.         Function {\em lexer()} processes the input file and depending on the
  10.         information returns a value from the {\em LEXER\_} enumerated type. The
  11.         semantic value of the input is stored in the lexical buffer {\em
  12.         lexbuf}.
  13.  
  14.         The following types of input are handled within {\em lexer()}, i.e.,
  15.         without returning:
  16.  
  17.         \begin{itemize}
  18.  
  19.             \item Newlines lead to the updating of the line counter associated
  20.             with the current file.
  21.  
  22.             \item Comments (// or /$*$ $*$/) are skipped.
  23.  
  24.             \item `\#' characters activate function {\em directive()}, which
  25.             processes a preprocessor directive. After the processing of the
  26.             directive, the input is further processed.
  27.  
  28.         \end{itemize}
  29.  
  30.         The following types of input lead to termination of {\em lexer()} by
  31.         returning:
  32.  
  33.         \begin{itemize}
  34.  
  35.             \item End of file: value {\em l\_eof} is returned.
  36.  
  37.             \item Spaces or tabs: value {\em l\_space} is returned, while the
  38.             read character is stored in {\em lexbuf[0]}.
  39.  
  40.             \item Double quotes: {\em l\_string} is returned, while the string
  41.             is stored in {\em lexbuf}. Note that the double quotes are not
  42.             stored in {\em lexbuf}.
  43.  
  44.             \item Identifiers (see {\em getident()} for a definition): {\em
  45.             l\_ident} is returned, while the identifier name is stored in {\em
  46.             lexbuf}. The identifier is read into the buffer by {\em
  47.             getident()}.
  48.  
  49.             \item Numbers (series of [0-9]): {\em l\_other} is returned, while
  50.             the read `pseudo-identifier' is stored in {\em lexbuf}.
  51.  
  52.             \item All other characters: {\em l\_single} is returned, while the
  53.             character is stored in {\em lexbuf[0]}.
  54.  
  55.         \end{itemize}
  56.     }
  57. */
  58.  
  59. #include "icm-pp.h"
  60.  
  61. LEXER_ lexer ()
  62. {
  63.     register int
  64.         state,
  65.         index,
  66.         ch;
  67.  
  68.     while (1)
  69.     {
  70.         ch = fgetc (filestack [filesp].f);
  71.         switch (ch)
  72.         {
  73.             case EOF:
  74.                 return (l_eof);
  75.             case '\n':
  76.                 filestack [filesp].l++;
  77.             case ' ':
  78.             case '\t':
  79.                 lexbuf [0] = ch;
  80.                 return (l_space);
  81.             case '\"':
  82.                 index = 0;
  83.                 while (1)
  84.                 {
  85.                     if ( (ch = fgetc (filestack [filesp].f)) == '\n' )
  86.                         error ("%s: %d: unterminated string, \" expected",
  87.                                filestack [filesp].n, filestack [filesp].l);
  88.                     else if (ch == '\\')
  89.                     {
  90.                         lexbuf [index++] = '\\';
  91.                         if ( (lexbuf [index++] =
  92.                               fgetc (filestack [filesp].f)) == (char) EOF
  93.                            )
  94.                             error ("%s: unterminated string at EOF",
  95.                                 filestack [filesp].n);
  96.                     }
  97.                     else if (ch == '\"')
  98.                     {
  99.                         lexbuf [index] = '\0';
  100.                         return (l_string);
  101.                     }
  102.                     else
  103.                         lexbuf [index++] = (char) ch;
  104.                 }
  105.             case '/':
  106.                 lexbuf [0] = '/';
  107.                 if ( (ch = fgetc (filestack [filesp].f)) == '/' )
  108.                 {
  109.                     while ( (ch = fgetc (filestack [filesp].f)) != '\n' &&
  110.                             ch != EOF
  111.                           )
  112.                             ;
  113.                     ungetc (ch, filestack [filesp].f);
  114.                     break;
  115.                 }
  116.                 else if (ch == '*')
  117.                 {
  118.                     state = 0;
  119.                     while (state != 2)
  120.                     {
  121.                         if ( (ch = fgetc (filestack [filesp].f)) == '\n')
  122.                         {
  123.                             filestack [filesp].l++;
  124.                             fputc ('\n', outfile);
  125.                         }
  126.                         else if (ch == EOF)
  127.                             error ("%s: %d: unterminated comment block",
  128.                                    filestack [filesp].n, filestack [filesp].l);
  129.                         switch (state)
  130.                         {
  131.                             case 0:
  132.                                 if (ch == '*')
  133.                                     state = 1;
  134.                                 break;
  135.                             case 1:
  136.                                 if (ch == '/')
  137.                                     state = 2;
  138.                                 else
  139.                                     state = 0;
  140.                                 break;
  141.                         }
  142.                     }
  143.                 }
  144.                 else
  145.                 {
  146.                     ungetc (ch, filestack [filesp].f);
  147.                     return (l_single);
  148.                 }
  149.                 break;
  150.             case '#':
  151.                 directive ();
  152.                 break;
  153.             default:
  154.                 if (ch == '_' || isalpha (ch))
  155.                 {
  156.                     ungetc (ch, filestack [filesp].f);
  157.                     getident (lexbuf);
  158.                     return (l_ident);
  159.                 }
  160.                 else if (isalnum (ch))
  161.                 {
  162.                     index = 0;
  163.                     while (isalnum (ch) || ch == '_')
  164.                     {
  165.                         lexbuf [index++] = (char) ch;
  166.                         ch = fgetc (filestack [filesp].f);
  167.                     }
  168.                     lexbuf [index] = '\0';
  169.                     ungetc (ch, filestack [filesp].f);
  170.                     return (l_other);
  171.                 }
  172.                 else
  173.                 {
  174.                     lexbuf [0] = (char) ch;
  175.                     return (l_single);
  176.                 }
  177.         }
  178.     }
  179. }
  180.